package com.surekam.mnai.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.surekam.mnai.dao.AddressDao;
import com.surekam.mnai.entity.LoadPattern;
import com.surekam.mnai.model.Address;

/**
 *IAddressService的实现类
 * @author caoxu
 */
@Component
@Transactional
public class AddressServiceImpl implements IAddressService {

	@Autowired
	private AddressDao dao;

	private String messageForError;

	@Override
	public Address addAddress(Address address) throws ServiceException {
		return templateOperation(address, "insert");
	}

	@Override
	public Address delAddress(Address address) {
		return templateOperation(address, "delete");
	}

	/**
	 * 返回错误信息提示
	 * 
	 * @return
	 */
	public String getMessageForError() {
		return messageForError;
	}
	
	@Override
	public Address loadById(String id) {
		if(id == null || "".equals(id)){
			setMessageForError("查询的id错误");
			return null;
		}
		try {
			return dao.queryById(id); 
		} catch (DataAccessException e) {
			e.printStackTrace(); //Debug
			setMessageForError(e.getMessage());
			return null;
		}
	}

	@Override
	public Address loadByProvinceAndCity(String province, String city) {
		boolean provinceIsValid = !(province == null || "".equals(province));
		boolean cityIsValid = !(city == null || "".equals(city));

		if (provinceIsValid && cityIsValid) {
			return dao.query(province, city);
		}
		return null;
	}

	@Override
	public List<Address> loadsByPattern(String term, LoadPattern pattern) {
		if (pattern == null) {
			setMessageForError("搜索的模式为空！");
			return null;
		}

		if (term == null || "".equals(term)) {
			return dao.queryAll();
		}

		switch (pattern) {
		case AREACODE:
			return loadsByAreaCode(term);
		case CITY:
			return loadsByCity(term);
		case POSTCODE:
			return loasByPostCode(term);
		case PROVINCE:
			return loadsByProvince(term);
		default:
			setMessageForError("loadsByPattern方法不支持" + pattern + "模式");
			return null;
		}
	}

	@Override
	public Address updateAddress(Address address) {
		return templateOperation(address, "udpate");
	}

	/**
	 * @param term
	 * @return
	 */
	private List<Address> loadsByAreaCode(String term) {
		return dao.queryByAreaCode(term);
	}

	/**
	 * @param term
	 * @return
	 */
	private List<Address> loadsByCity(String term) {
		return dao.queryByCity(term);
	}

	/**
	 * 根据省份返回地址集合
	 * 
	 * @param term
	 * @return
	 */
	private List<Address> loadsByProvince(String term) {
		return dao.queryByProvince(term);
	}

	/**
	 * @param term
	 * @return
	 */
	private List<Address> loasByPostCode(String term) {
		return dao.queryByPostCode(term);
	}

	/**
	 * 设置错误信息提示
	 *
	 * @param messageForError
	 *            错误信息
	 */
	private void setMessageForError(String messageForError) {
		this.messageForError = messageForError;
	}

	/**
	 * 对数据进行增删改操作的方法
	 * @param address
	 * @param operationName
	 * @return
	 */
	private Address templateOperation(Address address, String operationName){
		if (address == null) {
			setMessageForError("操作的对象为空！");
			return null;
		}
		boolean insertSucceeful = false; // 用于容错
		try {
			if ("insert".equals(operationName)) {
				dao.insert(address);
				insertSucceeful = true;
				return dao.query(address.getProvince(), address.getCity());
			}
			if ("update".equals(operationName)) {
				dao.update(address);
				return address;
			}
			if ("delete".equals(operationName)) {
				dao.deleteById(address.getAddressId());
				address.setAddressId(null);
				return address;
			}

		} catch (DataAccessException e) {
			e.printStackTrace();
			setMessageForError(e.getMessage());

			//对于添加操作执行成功而返回插入之后数据出现错误 返回插入数据，没有成功抛出异常
			if (insertSucceeful) {
				return address;
			} else if(!insertSucceeful){
				throw e;
			}
			return null;
		}
		return null;
	}

}
